package com.hqq.integration.publish_subscribe;

import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 发布-订阅模式用来实现广播的功能.观察者模式主要是被观察的对象在自身状态发生改变时通知观察者,发布订阅模式扩展了
 * 观察者模式,它通过添加事件管道来进行通知
 * <p>
 * 发布-订阅管道工作如下:
 * 1) 有一个发布-订阅管道 连接多个输出管道 每个输出管道连接一个订阅者.
 * 2) 当有一个事件被发布到管道中,发布订阅管道就会复制这条信息并且发送给所有的输出管道 传送给订阅者
 * <p>
 * 本例子使用了Apache的Camel建议一个发布订阅通道 从'direct-origin'发布信息到'mock:foo','mock:bar','stream:out'
 * <p>
 * Created by heqianqian on 2017/8/18.
 */
public class App {

    private static final Logger LOGGER = LoggerFactory.getLogger(App.class);

    public static void main(String[] args) throws Exception {
        CamelContext camelContext = new DefaultCamelContext();
        camelContext.addRoutes(new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                from("direct:origin").multicast().to("mock:foo", "mock:bar", "stream:out");
            }
        });
        ProducerTemplate template = camelContext.createProducerTemplate();
        //开启管道
        camelContext.start();
        //打印所有接受到的信息
        camelContext.getRoutes().forEach(route -> LOGGER.info(route.toString()));
        //输出数据到订阅者
        template.sendBody("direct:origin", "hello from origin");
        template.sendBody("direct:origin", "bye from origin");
        //关闭管道
        camelContext.stop();
    }
}
